package com.cskaoyan.user.service.impl;

import com.cskaoyan.mall.commons.constant.SysRetCodeConstants;
import com.cskaoyan.mall.commons.exception.ValidateException;
import com.cskaoyan.user.dal.entitys.Member;
import com.cskaoyan.user.dal.entitys.UserVerify;
import com.cskaoyan.user.dal.persistence.MemberMapper;
import com.cskaoyan.user.dal.persistence.UserVerifyMapper;
import com.cskaoyan.user.dto.UserRegisterResponse;
import com.cskaoyan.user.form.UserRegisterRequest;
import com.cskaoyan.user.form.UserVerifyRequest;
import com.cskaoyan.user.service.IUserRegisterService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.Date;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import tk.mybatis.mapper.entity.Example;

/**
 * @author 12-江涛
 * @since 2022/10/26  11:51
 */
@Service
public class IUserRegisterServiceImpl implements IUserRegisterService {

    @Autowired
    MemberMapper memberMapper;
    @Autowired
    UserVerifyMapper userVerifyMapper;
    @Autowired
    JavaMailSender mailSender;

    @Override
    public UserRegisterResponse register(UserRegisterRequest request) {
        UserRegisterResponse response = new UserRegisterResponse();
        // 1.向用户表中插入数据
        // 插入之前先判断用户是否存在(数据库中username、password、email设置了唯一，重复则插入失败)
        // 校验username，password、email是否合法
        int userNameLen = request.getUserName().length();
        String userPwd = request.getUserPwd();
        String email = request.getEmail();
        int pwdLen = userPwd.length();
        String regex1 = ".*[a-z]+.*";
        String regex2 = ".*[A-Z]+.*";
        boolean matches1 = Pattern.compile(regex1).matcher(userPwd).matches();
        boolean matches2 = Pattern.compile(regex2).matcher(userPwd).matches();
        if (userNameLen < 6 || userNameLen > 16) {
            response.setCode(SysRetCodeConstants.USERNAME_ILLEGAL.getCode());
            response.setMsg(SysRetCodeConstants.USERNAME_ILLEGAL.getMessage());
            return response;
        }
        if (pwdLen < 6 || pwdLen > 16 || !(matches1 && matches2)) {
            response.setCode(SysRetCodeConstants.PASSWORD_ILLEGAL.getCode());
            response.setMsg(SysRetCodeConstants.PASSWORD_ILLEGAL.getMessage());
            return response;
        }
        if (!Pattern.matches("^(\\w+([-.][A-Za-z0-9]+)*){3,18}@\\w+([-.][A-Za-z0-9]+)*\\.\\w+([-.][A-Za-z0-9]+)*$", email)) {
            response.setCode(SysRetCodeConstants.EMAIL_ILLEGAL.getCode());
            response.setMsg(SysRetCodeConstants.EMAIL_ILLEGAL.getMessage());
            return response;
        }
        Member member = new Member();
        member.setUsername(request.getUserName());
        member.setEmail(request.getEmail());
        // 对插入的password进行加密
        String password = DigestUtils.md5DigestAsHex(request.getUserPwd().getBytes());
        member.setPassword(password);
        member.setCreated(new Date());
        member.setUpdated(new Date());
        member.setIsVerified("N");
        member.setState(1);
        int i = 0;
        try {
            i = memberMapper.insertSelective(member);
        } catch (Exception e) {
            throw new ValidateException(SysRetCodeConstants.USER_EXIST.getCode(), SysRetCodeConstants.USER_EXIST.getMessage());
        }
        // 2.向用户验证表中插入数据
        // 用户表插入失败，返回失败信息
        if (i != 1) {
            response.setCode(SysRetCodeConstants.USER_REGISTER_FILED.getCode());
            response.setMsg(SysRetCodeConstants.USER_REGISTER_FILED.getMessage());
            return response;
        }
        // 用户表插入成功，向验证表中插入信息
        UserVerify userVerify = new UserVerify();
        userVerify.setUsername(request.getUserName());
        userVerify.setRegisterDate(new Date());
        String key = member.getUsername() + member.getPassword() + UUID.randomUUID().toString();
        String uuid = DigestUtils.md5DigestAsHex(key.getBytes());
        userVerify.setUuid(uuid);
        userVerify.setIsVerify("N");
        userVerify.setIsExpire("N");
        int row = userVerifyMapper.insertSelective(userVerify);
        if (row != 1) {
            response.setCode(SysRetCodeConstants.USER_REGISTER_VERIFY_FILED.getCode());
            response.setMsg(SysRetCodeConstants.USER_REGISTER_VERIFY_FILED.getMessage());
            return response;
        }


        // 3.发送用户激活邮箱
        try {
            sendEmail(uuid, request);
        } catch (Exception e) {
            response.setCode(SysRetCodeConstants.EMAIL_ILLEGAL.getCode());
            response.setMsg(SysRetCodeConstants.EMAIL_ILLEGAL.getMessage());
            return response;
        }

        response.setCode(SysRetCodeConstants.SUCCESS.getCode());
        response.setMsg(SysRetCodeConstants.SUCCESS.getMessage());
        return response;
    }

    /**
     * 发送用户激活邮件
     *
     * @param uuid
     * @param request
     */
    private void sendEmail(String uuid, UserRegisterRequest request) {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setSubject("用户激活");
        message.setFrom("jidian000118@163.com");
        message.setTo(request.getEmail());
        StringBuffer str = new StringBuffer();
        str.append("http://localhost:8080/user/verify?uid=").append(uuid).append("&username=").append(request.getUserName());
        message.setText(str.toString());
        mailSender.send(message);

    }


    @Override
    public void verify(UserVerifyRequest request) {

        //修改user_Verify表
        Example example = new Example(UserVerify.class);
        example.createCriteria().andEqualTo(request.getUuid());
        UserVerify userVerify = new UserVerify();
        userVerify.setIsVerify("Y");
        userVerifyMapper.updateByExampleSelective(userVerify, example);

        //修改用户表
        Example example1 = new Example(Member.class);
        example1.createCriteria().andEqualTo(request.getUsername());
        Member member = new Member();
        member.setIsVerified("Y");
        memberMapper.updateByExampleSelective(member, example1);

    }
}
